#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import re
from datetime import datetime, timedelta
import traceback
import pandas as pd
import time
import warnings
from typing import Optional, Union, List, Dict, Any
from pathlib import Path
import itertools
from functools import partial

import re


def fprint(msg, file):
    with open(file, "w", encoding="utf-8") as f:
        # 将print的内容写入文件
        print(msg, file=f)

def remove_chinese(text):
    # 匹配所有中文字符（包括标点符号）
    pattern = re.compile(r'[\u4e00-\u9fff\u3000-\u303f\uff00-\uffef]')
    return pattern.sub('', text)

def keep_english_digits_space(text):
    # 只保留英文字母(a-zA-Z)、数字(0-9)和空格
    text = re.sub(r'[^a-zA-Z0-9 ]', ' ', text)
    return re.sub(r' +', ' ', text)

def lget(lst, index, default=None):
    if -len(lst) <= index < len(lst):
        return lst[index]
    else:
        return default

def tryUntilSuccess(funcs,name='This function',max_attempts=13):
    """
    无限循环执行函数数组，直到某个函数执行成功。
    :param funcs: 包含函数和参数的可调用对象列表
    """
    attempts = 1  # 当前尝试次数
    for func in itertools.cycle(funcs):
        try:
            func()  # 执行函数
            print(f"Function {func.func.__name__} executed successfully.")
            break  # 成功执行后退出循环
        except Exception:
            print(f"tryUntilSucess第{attempts}次尝试，Function {func.func.__name__} failed with error! ")
            #traceback.print_exc()
            attempts += 1
            if attempts >= max_attempts:
                traceback.print_exc()
                raise RuntimeError(f"{name}, Exceeded maximum attempts ({max_attempts}). No tasks succeeded.")
            continue  # 继续
        
def get_memory_usage(df: pd.DataFrame) -> str:
    """获取DataFrame的内存使用情况"""
    memory_usage = df.memory_usage(deep=True).sum()
    return f"{memory_usage / 1024 / 1024:.2f} MB"


def parse_wrapper(excel_file, **kwargs):
    print(kwargs)
    print(f"{kwargs['name']},begin...")
    start_time = time.time()
    df = excel_file.parse(**{k: v for k, v in kwargs.items() if k not in ['name', 'path']})
    end_time = time.time()
    elaspse_time = end_time - start_time
    print(f"{kwargs['name']}, 体积：{get_memory_usage(df)}, 行数: {df.shape[0]}, 耗时：{elaspse_time:2f}")
    return df


def ExcelFiles(files: list, this_pd=None):
    excels = {}
    dfs = {}
    if not this_pd:
        this_pd = pd
    for f in files:
        excel_ID = str(hash(f['path']))
        if excel_ID not in excels:
            excels[excel_ID] = []
        excels[excel_ID].append(f)

    # Create an ExcelFile object
    for k, sheets in excels.items():
        excel_file = this_pd.ExcelFile(sheets[0]['path'], engine='openpyxl')
        # Read a specific sheet and specify columns to read
        # You can specify columns by their names or by their indices
        dfs.update({sheet['name']: parse_wrapper(excel_file, **sheet) for sheet in sheets})

    print("ends all...")
    return dfs

def datestrFormat(dt: str):
    pattern = r'^\d{1,2}\.[A-Za-z]{3}$'
    pattern2 = r'^\d{8}$'
    isfull = False
    if re.match(pattern, dt):
        dt = datetime.strptime(dt, "%d.%b")
        dt = dt.replace(year=datetime.now().year)
    elif re.match(pattern2, dt):
        dt = datetime.strptime(dt, "%Y%m%d")
        isfull = True
    else:
        dt_arr = [int(item) for item in dt.split('.')]
        this_year = datetime.now().year
        dt = datetime(this_year, *dt_arr)
    if not isfull:
        # 获取当前日期; 计算日期差异
        current_date = datetime.now()
        date_diff = current_date - dt
        # print(date_diff)
        # 如果相差超过6个月（约180天），则将字符日期加一年
        if date_diff > timedelta(days=180):
            # print("overhaul")
            dt = dt.replace(year=dt.year + 1)
    flightDate = dt.strftime("%Y-%m-%d")

    """
        strptime -->时间类型
        strftime -->字符类型
    """
    return flightDate

def split_random_number(total:int, n:int):
    if total < 2:
        return [0 for _ in range(n)]
    # 生成n-1个随机数并排序
    random_points = sorted([random.randint(1, total - 1) for _ in range(n - 1)])
    # 计算每一份的值
    parts = [random_points[0]] + [random_points[i]-random_points[i-1] for i in range(1,len(random_points))] + [total-random_points[-1]]
    return parts

def rename_with_pathlib(target_dir, filename):
    """使用pathlib的实现版本"""
    # 目标路径
    print(f"target_dir:{target_dir},filename:{filename}")
    target_file = target_dir / filename
    # 1. 确保目标目录存在
    try:
        target_dir.mkdir(parents=True, exist_ok=True)
    except Exception as e:
        print(f"创建目录失败: {e}")
        return
    # 2. 检查目标文件是否存在
    if target_file.exists():
        print(f"文件 {target_file} 已存在，跳过操作")
        return target_file
    # 3. 查找所有xlsx文件
    xlsx_files = list(Path(target_dir).glob('*.xlsx'))
    print("xlsx_files:", xlsx_files)
    if not xlsx_files:
        print("没有找到任何.xlsx文件")
        return
    # 4. 获取第一个文件
    first_file = sorted(xlsx_files)[0]
    try:
        # 5. 重命名并移动文件
        first_file.replace(target_file)
        print(f"成功将 '{first_file}' 移动并重命名为 '{target_file}'")
    except Exception as e:
        print(f"操作失败: {e}")
    return target_file
